package B刷题.A栈和队列;

import java.util.LinkedList;
import java.util.Queue;

/**
 * @author wei.zhao
 * @description: 程序员代码面试指南：猫狗队列
 * @date 2022年12月03日 8:44
 */
public class Code05_DogCatQueue {

    /**
     * 注意：
     * 1.为什么不能使用时间戳?
     *   同一毫秒插入两条数据怎么办！
     * 2.count表示的到底是什么，为什么弹出不减减？
     *   count表示的是该条数据进队列的次序，所以不用减减；
     *   一旦减减了，假如前面有16条数据，现在弹出前15条，后面进来的次序就成了2，反而在原来的第16条之前了！
     * 队列里放的不一定就是原对象，也可以是原对象加工出来的新对象。
     */
    private Queue<PetWithStamp> dogQueue;
    private Queue<PetWithStamp> catQueue;
    private long count;

    public Code05_DogCatQueue() {
        dogQueue = new LinkedList<>();
        catQueue = new LinkedList<>();
    }

    /**
     * 添加宠物
     */
    public void add(Pet pet) {
        PetWithStamp petWithStamp = new PetWithStamp(pet, count++);
        if (pet.getType().equals("dog")) {
            dogQueue.add(petWithStamp);
        } else if (pet.getType().equals("cat")) {
            catQueue.add(petWithStamp);
        } else {
            throw new RuntimeException("没有该类型的宠物");
        }
    }

    /**
     * 弹出宠物
     */
    public Pet pollAll() {
        if (!dogQueue.isEmpty() && !catQueue.isEmpty()) {
            if (dogQueue.peek().stamp < catQueue.peek().stamp) {
                return dogQueue.poll().getPet();
            } else {
                return catQueue.poll().getPet();
            }
        } else if (!dogQueue.isEmpty()) {
            return dogQueue.poll().getPet();
        } else if (!catQueue.isEmpty()) {
            return catQueue.poll().getPet();
        } else {
            throw new RuntimeException("队列为空");
        }
    }

    /**
     * 弹出狗
     */
    public Dog pollDog() {
        if (dogQueue.isEmpty()) {
            throw new RuntimeException("狗队列为空");
        } else {
            return (Dog) dogQueue.poll().getPet();
        }
    }

    /**
     * 弹出猫
     */
    public Cat pollCat() {
        if (catQueue.isEmpty()) {
            throw new RuntimeException("狗队列为空");
        } else {
            return (Cat) catQueue.poll().getPet();
        }
    }

    /**
     * 是否空
     */
    public boolean isEmpty() {
        if (dogQueue.isEmpty() && catQueue.isEmpty()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 是否还有狗
     */
    public boolean isDogQueueEmpty() {
        return dogQueue.isEmpty();
    }

    /**
     * 是否还有猫
     */
    public boolean isCatQueueEmpty() {
        return catQueue.isEmpty();
    }

    public static class Pet {
        private String type;

        public Pet(String type) {
            this.type = type;
        }

        public String getType() {
            return type;
        }
    }

    public static class Dog extends Pet {
        public Dog() {
            super("dog");
        }
    }

    public static class Cat extends Pet {
        public Cat() {
            super("cat");
        }
    }

    public static class PetWithStamp {
        private Pet pet;
        private long stamp;

        public PetWithStamp(Pet pet, long stamp) {
            this.pet = pet;
            this.stamp = stamp;
        }

        public long getStamp() {
            return stamp;
        }

        public Pet getPet() {
            return pet;
        }
    }
}
